package org.brownflat.lighthouse.monitoring.monitor;

import org.apache.log4j.Logger;
import org.brownflat.lighthouse.monitoring.ci.Build;
import org.brownflat.lighthouse.monitoring.ci.Feed;
import org.brownflat.lighthouse.monitoring.ci.Monitorable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

public class SimpleMonitoringService implements MonitoringService {

    private Executor executor;
    private List<LighthouseTask> active = new ArrayList<LighthouseTask>();
    private List<LighthouseTask> paused = new ArrayList<LighthouseTask>();
    private static final Logger LOG = Logger.getLogger(SimpleMonitoringService.class);

    public SimpleMonitoringService(Executor executor) {
        this.executor = executor;
    }

    public SimpleMonitoringService(Executor executor, List<LighthouseTask> tasks) {
        this.executor = executor;
        for(LighthouseTask task : tasks) {
            pause(task);
        }
    }

    public void addTask(LighthouseTask task) {
        pause(task);
    }

    @Override
    public List<LighthouseTask> getAllTasks() {
        List<LighthouseTask> allTasks = new ArrayList<LighthouseTask>();
        allTasks.addAll(active);
        allTasks.addAll(paused);
        return allTasks;
    }

    @Override
    public List<Build> getLatestBuilds() {
        List<Build> builds = new ArrayList<Build>();

        for(LighthouseTask task : active) {
            Monitorable monitorable = task.getMonitorable();
            Feed feed = monitorable.getLatestFeed();
            Map<String, Build> latestBuilds = feed.buildLatestBuildHistory();
            builds.addAll(latestBuilds.values());
        }
        return builds;
    }

    public List<LighthouseTask> activeTasks() {
        return Collections.unmodifiableList(active);
    }

    public List<LighthouseTask> pausedTasks() {
        return Collections.unmodifiableList(paused);
    }

    @Override
    public boolean pause() {
        for (Iterator iterator = active.iterator(); iterator.hasNext(); ) {
            LighthouseTask task = (LighthouseTask) iterator.next();
            pause(task);
            iterator.remove();
        }
        return true;
    }

    @Override
    public boolean pause(String name) {
        for (Iterator iterator = active.iterator(); iterator.hasNext(); ) {
            LighthouseTask task = (LighthouseTask) iterator.next();
            if (task.getName().equals(name)) {
                pause(task);
                iterator.remove();
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean start() {
        for (Iterator iterator = paused.iterator(); iterator.hasNext(); ) {
            LighthouseTask task = (LighthouseTask) iterator.next();
            activate(task);
            iterator.remove();
        }
        return true;
    }

    @Override
    public boolean start(String name) {
        for (Iterator iterator = paused.iterator(); iterator.hasNext(); ) {
            LighthouseTask task = (LighthouseTask) iterator.next();
            if (task.getName().equals(name)) {
                activate(task);
                iterator.remove();
                return true;
            }
        }
        return false;
    }

    public void run() {
        for (LighthouseTask task : active) {
            LOG.debug("Executing " + task.getName());
            executor.execute(task);
        }
    }

    private void pause(LighthouseTask task) {
        task.setActive(false);
        paused.add(task);
    }

    private void activate(LighthouseTask task) {
        task.setActive(true);
        active.add(task);
    }
}
